import User from '../../user/user';
import GeneralConfig from '../config/general-config';
import CommonService from './common-service';
import LocalStorageService from './local-storage-service';
import RememberMeService from './remember-me-service';
import TokenService from './token-service';

/**
 * The service provides method against authentication.
 *
 * Current active user info is saved in local storage with key [GeneralConfig.localUserInfoStorageKey].
 * This is used to determine if user is logged in or not.
 *
 * The active user access token is saved in local storage with key [GeneralConfig.localAccessTokenStorageKey].
 *
 * IMPORTANT!!!
 * Never ever saves user plain password on client side!!!
 */
export default class AuthenticationService {
  // Loads the user from session storage at the first time.
  static currentUser: User | null =
    RememberMeService.rememberMe ? LocalStorageService.loadLocalData(GeneralConfig.localUserInfoStorageKey, null) as User | null :
      LocalStorageService.loadSessionData(GeneralConfig.localUserInfoStorageKey, null) as User | null;

  static currentUsername: string | null = LocalStorageService.loadLocalData(GeneralConfig.localCurrentUsernameStorageKey);

  // Sets authentication status based on local user and token info.
  static isAuthenticated: boolean = this.currentUser != null && TokenService.hasRefreshToken;

  /**
   * Notifies the observer that user has logged out.
   * @param user The user object that will be sent to all observers.
   */
  static saveUserInfo(user: any): void {
    this.isAuthenticated = true;
    this.currentUser = user;

    if (RememberMeService.rememberMe === true) {
      // Removes session data just in case.
      LocalStorageService.removeSessionData(GeneralConfig.localUserInfoStorageKey);

      // If users checks 'remember me' the data will be saved in local storage.
      LocalStorageService.saveLocalData(GeneralConfig.localUserInfoStorageKey, user);
    } else {
      // Removes the local data just in case.
      LocalStorageService.removeLocalData(GeneralConfig.localUserInfoStorageKey);

      // If users does NOT check 'remember me' the data will be saved in session storage.
      // Onces user closes the browser the session storage will be auto cleared.
      LocalStorageService.saveSessionData(GeneralConfig.localUserInfoStorageKey, user);
    }
  }

  /**
   * Saves current username. This is for logic form with saved username.
   */
  static saveCurrentUsername(username?: string | null): void {
    // [currentUser] will be null if user is not logged in yet.
    if (CommonService.isNullOrUndefinedOrEmptyString(username) && this.currentUser != null) {
      username = this.currentUser.username;
    }

    if (!CommonService.isNullOrUndefinedOrEmptyString(username)) {
      LocalStorageService.saveLocalData(GeneralConfig.localCurrentUsernameStorageKey, username);
    }
  }

  /**
   * Removes current username. This is for logic form with saved username.
   */
  static removeCurrentUsername(): void {
    LocalStorageService.removeLocalData(GeneralConfig.localCurrentUsernameStorageKey);
  }

  /**
   * Notifies the observer that user has logged out and clears the redirectUrl.
   */
  static removeUserInfo(): void {
    LocalStorageService.removeLocalData(GeneralConfig.localUserInfoStorageKey);
    LocalStorageService.removeSessionData(GeneralConfig.localUserInfoStorageKey);
    this.isAuthenticated = false;
    this.currentUser = null;
    // redirectUrl = null;
  }
}